﻿#region Librerias

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Windows.Media.Imaging;
using ESF.General;
using iTextSharp.text.pdf;
using iTextSharp.text;
using System.Reflection;

#endregion


namespace ESF.FileProcessing
{
	public static class ProcessFileHelper
	{
		public enum RenameActions
		{
			JustCopyRenamed,
			OnlyIfExistsRename,
			RenameAndOverwrite,
			DontRenameOverwrite,
			DoNothingIfExists
		}


		public static string [] ExtractImages (string pFileName)
		{
			switch (Path.GetExtension(pFileName).ToUpper())
			{
				case ".JPG":
				case ".JPEG":
				case ".BMP":
				case ".GIF":
				case ".TIF":
					return TIFFHelper.ExtractImages (pFileName);

				//case ".PDF":
				//	return PDFHelper.GetItemCount(pFileName);
				default:
					throw new NotSupportedException (string.Format ("Format for file is not supported: {0}", pFileName));
			}
		}


		public static int? GetItemCount(string pFileName)
		{
			switch (Path.GetExtension(pFileName).ToUpper())
			{
				case ".TIF":
					return TIFFHelper.GetItemCount (pFileName);

				case ".JPG":
				case ".JPEG":
				case ".BMP":
				case ".GIF":
					return 1;

				case ".PDF":
					return PDFHelper.GetItemCount (pFileName);
			}

			return null;
		}


		public static void MoveDirectories 
		(
			string pOriginDirectoryPath, string pDestinationDirectoryPath, 
			RenameActions pRenameActions,
			string pFormatReNAME,
			TextWriter pLogger,
			params string [] pFileExtensions
		)
		{
			CopyDirectories 
			(
				pOriginDirectoryPath, pDestinationDirectoryPath, 
				pRenameActions,
				pFormatReNAME,
				pLogger,
				true,
				pFileExtensions
			);
		}


		public static void CopyDirectories 
		(
			string pOriginDirectoryPath, string pDestinationDirectoryPath, 
			RenameActions pRenameActions,
			string pFormatReNAME,
			TextWriter pLogger,
			params string [] pFileExtensions			
		)
		{
			CopyDirectories
			(
				pOriginDirectoryPath, pDestinationDirectoryPath,
				pRenameActions,
				pFormatReNAME,
				pLogger,
				false,
				pFileExtensions
			);
		}


		public static void CopyDirectories 
		(
			string pOriginDirectoryPath, string pDestinationDirectoryPath, 
			RenameActions pRenameActions,
			string pFormatReNAME,
			TextWriter pLogger,
			bool pDeleteAfterCopy,
			params string [] pFileExtensions			
		)
		{
			pOriginDirectoryPath = FileHelper.AddFinalSeparator (pOriginDirectoryPath);
			pDestinationDirectoryPath = FileHelper.AddFinalSeparator (pDestinationDirectoryPath);

			if (!Directory.Exists (pOriginDirectoryPath))
			{
				throw new GenericInfoException (string.Format ("El directorio de origen {0} no existe", pOriginDirectoryPath));
			}

			if (!Directory.Exists(pDestinationDirectoryPath))
			{
				throw new GenericInfoException(string.Format("El directorio de destino {0} no existe", pDestinationDirectoryPath));
			}

			if (string.IsNullOrWhiteSpace (pFormatReNAME))
			{
				pFormatReNAME = "{0}";
			}


			pLogger.WriteLine ("Iniciando copia desde:");
			pLogger.WriteLine("Origen: {0}", pOriginDirectoryPath);
			pLogger.WriteLine ("Destino: {0}", pDestinationDirectoryPath);

			if (!DataHelper.IsEmpty(pFileExtensions))
			{
				pLogger.Write("Extensiones incluidas: ");
				pLogger.WriteLine(TextHelper.Concatenate(", ", pFileExtensions));
			}

			pLogger.WriteLine();


			FileHelper.ExecuteInDirectoryFiles (pOriginDirectoryPath,
					delegate (string pFileName, object [] pExtras)
					{
						// Se copia un archivo desde una ubicacion con una posible jerarquia de carpetas equivalente en el destino
						// Ejemplo: 
						// Origen: c:\Image Catalog\Salud\Catalog A\Bogota X\Fotos\123456.tif
						// Destino: c:\Image Catalog\Salud\Catalog A\Bogota Consolidado\Fotos\123456.tif
						// La idea es que el resultado si le ponen un formato por ejemplo: {0}_X (para el nombre del archivo)
						// el resultado sea en el destino almacendo como
						// Destino (original): c:\Image Catalog\Salud\Catalog A\Bogota Consolidado\Fotos\123456.tif
						// Resultado (copiado): c:\Image Catalog\Salud\Catalog A\Bogota Consolidado\Fotos\123456_X.tif
					
						string destinationFolderRelativePath;
						string destinationFileName;
						bool fileExists = false;


						pLogger.WriteLine ("Procesando el archivo {0}", pFileName);

						destinationFolderRelativePath = Path.GetDirectoryName (pFileName).Substring (pOriginDirectoryPath.Length);
						
						destinationFolderRelativePath = Path.Combine (pDestinationDirectoryPath, destinationFolderRelativePath);

						// Se ubica la ruta en el destino, si no existe se crea
						FileHelper.EnsureFolder (destinationFolderRelativePath);


						destinationFileName = Path.Combine (destinationFolderRelativePath, Path.GetFileName (pFileName));

						switch (pRenameActions)
						{
							// No se copia el archivo
							default:
							break;

							case RenameActions.JustCopyRenamed:
								// se ajusta el nombre del archivo de destino
								destinationFileName =
									Path.Combine(
										Path.GetDirectoryName(destinationFileName),
										string.Format(pFormatReNAME, Path.GetFileNameWithoutExtension(destinationFileName)) +
											Path.GetExtension(destinationFileName));

								fileExists = File.Exists(destinationFileName);

								if (fileExists)
								{
									FileHelper.Delete (destinationFileName);									
								}
								
								pLogger.WriteLine("Copiado a {0} con renombrado {1}, existia {2}", destinationFileName, pRenameActions, fileExists); 
									
								File.Copy(pFileName, destinationFileName);

							break;

							case RenameActions.DontRenameOverwrite:
								fileExists = File.Exists(destinationFileName);

								FileHelper.Delete (destinationFileName);

								pLogger.WriteLine("Copiado a {0} con renombrado {1}, existia {2}", destinationFileName, pRenameActions, fileExists);
								
								File.Copy (pFileName, destinationFileName);
							break;

							case RenameActions.OnlyIfExistsRename:
								fileExists = File.Exists (destinationFileName);
								
								if (fileExists)
								{
									// se ajusta el nombre del archivo de destino
									destinationFileName = 
										Path.Combine (
											Path.GetDirectoryName (destinationFileName), 
											string.Format (pFormatReNAME, Path.GetFileNameWithoutExtension (destinationFileName)) + 
												Path.GetExtension (destinationFileName));

									FileHelper.Delete (destinationFileName);
								}
								
								pLogger.WriteLine("Copiado a {0} con renombrado {1}, existia {2}", destinationFileName, pRenameActions, fileExists); 
									
								File.Copy(pFileName, destinationFileName);
								
							break;

							case RenameActions.RenameAndOverwrite:
								// se ajusta el nombre del archivo de destino
								destinationFileName = 
									Path.Combine (
										Path.GetDirectoryName (destinationFileName), 
										string.Format (pFormatReNAME, Path.GetFileNameWithoutExtension (destinationFileName)) + 
											Path.GetExtension (destinationFileName));
								
								fileExists = File.Exists (destinationFileName);
								
								FileHelper.Delete (destinationFileName);

								pLogger.WriteLine("Copiado a {0} con renombrado {1}, existia {2}", destinationFileName, pRenameActions, fileExists);

								File.Copy (pFileName, destinationFileName);
							break;
						}


						// Si se indica a pDeleteAfterCopy como true se elimina el archivo original
						if (pDeleteAfterCopy)
						{
							FileHelper.Delete (pFileName);
						}

						pLogger.WriteLine ();


					},pFileExtensions: pFileExtensions);
		}
	}
}
